﻿using UnityEngine;
using System.Collections.Generic;
using VoxelBlock;using Vector3Int = VoxelBlock.Vector3Int;


namespace VoxelBlock.VoxelBlock3D
{
    public sealed class Voxel3D
    {
        public int chunkKey;
        public byte selectKey = 255;
        /// <summary>
        /// 是否已经完成写入
        /// </summary>
        public bool isWrite = false;

        public int uvKey;
        public Vector3Int localPosition;
        public Vector3Int worldPosition;
        public int worldIndex;

        public int chunkIndex;
        /// <summary>
        /// 六个方向面
        /// </summary>
        public bool[] surfaces = new bool[6] { true, true, true, true, true, true };

        public ByteTo8Bool[] colorShadows = new ByteTo8Bool[6]
        {
            new ByteTo8Bool(false),
            new ByteTo8Bool(false),
            new ByteTo8Bool(false),
            new ByteTo8Bool(false),
            new ByteTo8Bool(false),
            new ByteTo8Bool(false)
        };

        public byte[][] colorShadow = new byte[6][]
        {
            new byte[4]{0,0,0,0}, 
            new byte[4]{0,0,0,0}, 
            new byte[4]{0,0,0,0}, 
            new byte[4]{0,0,0,0}, 
            new byte[4]{0,0,0,0}, 
            new byte[4]{0,0,0,0} 
        };

        /// <summary>
        /// 是否是边境
        /// </summary>
        public bool IsBorder { get; set; }

        /// <summary>
        /// 如果是边境，指出具体是哪个边境
        /// </summary>
        public bool[] specificBorders;

        public Voxel3D(Vector3Int a_Position, int uvkey)
        {
            this.uvKey = uvkey;
            this.worldPosition = a_Position;
        }

        public Voxel3D(Vector3Int a_Position, int uvkey, byte selectKey)
        {
            this.uvKey = uvkey;
            this.worldPosition = a_Position;
            this.selectKey = selectKey;
        }

        public Voxel3D(Vector3Int a_Position, Vector2Int a_UV)
        {
            this.uvKey = a_UV.x + a_UV.y * VoxelCategories.MAX_UV_X;
            this.worldPosition = a_Position;
        }
        /// <summary>
        /// 初始化ChunkIndex IsBorder
        /// </summary>
        public void StartData(Vector3Int position) 
        {
            this.localPosition = position; 
            
            int x = position.x;
            int y = position.y;
            int z = position.z;
            this.chunkIndex = x + (y << 4) + (z << 8);

            worldIndex = (worldPosition.x + 128) + ((worldPosition.y + 1) << 8) + ((worldPosition.z + 128) << 16);
            return;
            //this.worldIndex = (worldPosition.x + 128) + ((worldPosition.y + 1) << 8) + ((worldPosition.z + 128) << 16); ;


            IsBorder = false;
            bool[] var_Set_Array_Border = new bool[6];
            if (x == 0)
            {
                IsBorder = true;
                var_Set_Array_Border[1] = true;
            }
            else if (x == 15)
            {
                IsBorder = true;
                var_Set_Array_Border[0] = true;
            }


            if (y == 0)
            {
                IsBorder = true;
                var_Set_Array_Border[3] = true;
            }
            else if (y == 15)
            {
                IsBorder = true;
                var_Set_Array_Border[2] = true;
            }


            if (z == 0)
            {
                IsBorder = true;
                var_Set_Array_Border[5] = true;
            }
            else if (z == 15)
            {
                IsBorder = true;
                var_Set_Array_Border[4] = true;
            }
            if (IsBorder)
            {
                specificBorders = var_Set_Array_Border;
            }

        }
     

        /// <summary>
        /// x不超过2^15(32768 - 1) y不超过2^16(65536 - 1)
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return localPosition.GetHashCode();
        }

        /// <summary>
        /// 使用Key里面的数据
        /// </summary>
        /// <param name="a_Key">Key</param>
        /// <returns></returns>
        public Voxel3D FoKeySetVector3(int a_Key)
        {
            return new Voxel3D(Vector3Int.ToVoxel3D(a_Key), uvKey);
        }

        public static Voxel3D ToVoxel3D(int a_Key, Vector2Int a_UV)
        {
            return new Voxel3D(Vector3Int.ToVoxel3D(a_Key), a_UV);
        }

        public int GetWorldIndex(int direction)
        {
            switch (direction)
            {
                case 0:
                    return worldIndex + 1;
                case 1:
                    return worldIndex - 1;
                case 2:
                    return worldIndex + 256;
                case 3:
                    return worldIndex - 256;
                case 4:
                    return worldIndex + 65536;
                case 5:
                    return worldIndex - 65536;
            }
            return worldIndex;
        }


        /// <summary>
        /// 获得Chunk 共轭坐标
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static int GetChunkIndexBorderChunkConjugate(int chunkIndex , int direction)
        {
            switch (direction)
            {
                case 0:
                    return chunkIndex - 0x00F;
                case 1:
                    return chunkIndex + 0x00F;
                case 2:
                    return chunkIndex - 0x0F0;
                case 3:
                    return chunkIndex + 0x0F0;
                case 4:
                    return chunkIndex - 0xF00;
                case 5:
                    return chunkIndex + 0xF00;
            }
            return chunkIndex;
        }



        /// <summary>
        /// 获得Chunk 共轭坐标
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public int GetChunkIndexBorderChunkConjugate(int direction)
        {
            switch (direction)
            {
                case 0:
                    return chunkIndex - 0x00F;
                case 1:
                    return chunkIndex + 0x00F;
                case 2:
                    return chunkIndex - 0x0F0;
                case 3:
                    return chunkIndex + 0x0F0;
                case 4:
                    return chunkIndex - 0xF00;
                case 5:
                    return chunkIndex + 0xF00;
            }

            return chunkIndex;
        }

        /// <summary>
        /// 获得对边的boldk ，非边境
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="colorShadowIndex"></param>
        public int[] GetChunkEdgeIndexNoBorder(int direction)
        {
            int[] edgeBlockIndexs = new int[4];
            switch (direction)
            {
                case 0:
                    edgeBlockIndexs[0] = chunkIndex + 17;
                    edgeBlockIndexs[1] = chunkIndex - 15;
                    edgeBlockIndexs[2] = chunkIndex - 255;
                    edgeBlockIndexs[3] = chunkIndex + 257;
                    break;
                case 1:
                    edgeBlockIndexs[0] = chunkIndex + 15;
                    edgeBlockIndexs[1] = chunkIndex - 17;
                    edgeBlockIndexs[2] = chunkIndex + 255;
                    edgeBlockIndexs[3] = chunkIndex - 257;
                    break;
                case 2:
                    edgeBlockIndexs[0] = chunkIndex + 272;
                    edgeBlockIndexs[1] = chunkIndex - 240;
                    edgeBlockIndexs[2] = chunkIndex + 15;
                    edgeBlockIndexs[3] = chunkIndex + 17;
                    break;
                case 3:
                    edgeBlockIndexs[0] = chunkIndex - 272;
                    edgeBlockIndexs[1] = chunkIndex + 240;
                    edgeBlockIndexs[2] = chunkIndex - 17;
                    edgeBlockIndexs[3] = chunkIndex - 15;
                    break;
                case 4:
                    edgeBlockIndexs[0] = chunkIndex + 272;
                    edgeBlockIndexs[1] = chunkIndex + 240;
                    edgeBlockIndexs[2] = chunkIndex + 257;
                    edgeBlockIndexs[3] = chunkIndex + 255;
                    break;
                case 5:
                    edgeBlockIndexs[0] = chunkIndex - 240;
                    edgeBlockIndexs[1] = chunkIndex - 272;
                    edgeBlockIndexs[2] = chunkIndex - 257;
                    edgeBlockIndexs[3] = chunkIndex - 255;
                    break;
            }
            return edgeBlockIndexs;
        }

        /// <summary>
        /// 获得对角的boldk ，非边境
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public int[] GetChunkCornerIndexNoBorder(int direction)
        {
            int[] edgeBlockIndexs = new int[4];
            switch (direction)
            {
                case 0:
                    edgeBlockIndexs[0] = chunkIndex + 273;
                    edgeBlockIndexs[1] = chunkIndex - 271;
                    edgeBlockIndexs[2] = chunkIndex - 239;
                    edgeBlockIndexs[3] = chunkIndex + 241;
                    //1, 16 , 256
                    //1, -1, -1

                    //edgeVector3Ints[0] = voxel3D.worldPosition + new Vector3Int(1, 1, 0);
                    //edgeVector3Ints[1] = voxel3D.worldPosition + new Vector3Int(1, -1, 0);
                    //edgeVector3Ints[2] = voxel3D.worldPosition + new Vector3Int(1, 0, -1);
                    //edgeVector3Ints[3] = voxel3D.worldPosition + new Vector3Int(1, 0, 1);
                    break;
                case 1:
                    edgeBlockIndexs[0] = chunkIndex - 241;
                    edgeBlockIndexs[1] = chunkIndex + 239;
                    edgeBlockIndexs[2] = chunkIndex + 271;
                    edgeBlockIndexs[3] = chunkIndex - 273;
                    break;
                    //case 2:
                    //    edgeBlockIndexs[0] = chunkIndex + 272;
                    //    edgeBlockIndexs[1] = chunkIndex - 240;
                    //    edgeBlockIndexs[2] = chunkIndex + 15;
                    //    edgeBlockIndexs[3] = chunkIndex + 17;
                    //    break;
                    //case 3:
                    //    edgeBlockIndexs[0] = chunkIndex - 272;
                    //    edgeBlockIndexs[1] = chunkIndex + 240;
                    //    edgeBlockIndexs[2] = chunkIndex - 17;
                    //    edgeBlockIndexs[3] = chunkIndex - 15;
                    //    break;
                    //case 4:
                    //    edgeBlockIndexs[0] = chunkIndex + 272;
                    //    edgeBlockIndexs[1] = chunkIndex + 240;
                    //    edgeBlockIndexs[2] = chunkIndex + 257;
                    //    edgeBlockIndexs[3] = chunkIndex + 255;
                    //    break;
                    //case 5:
                    //    edgeBlockIndexs[0] = chunkIndex - 240;
                    //    edgeBlockIndexs[1] = chunkIndex - 272;
                    //    edgeBlockIndexs[2] = chunkIndex - 257;
                    //    edgeBlockIndexs[3] = chunkIndex - 255;
                    //    break;
            }
            return edgeBlockIndexs;
        }


        public void SetNewColorShadow(int direction3D)
        {
            colorShadows[direction3D].SetValue(0);
        }

        private void SetColorShadowAdd(int direction3D, int direction2D)
        {
            colorShadows[direction3D][direction2D] = true;
            return;
            switch (direction2D)
            {
                case 0:
                    colorShadow[direction3D][2] = 1;
                    colorShadow[direction3D][3] = 1;
                    break;
                case 1:
                    colorShadow[direction3D][0] = 1;
                    colorShadow[direction3D][1] = 1;
                    break;
                case 2:
                    colorShadow[direction3D][2] = 1;
                    colorShadow[direction3D][1] = 1;
                    break;
                case 3:
                    colorShadow[direction3D][3] = 1;
                    colorShadow[direction3D][0] = 1;
                    break;
            }
        }

        private void SetColorShadowRemove(int direction3D, int direction2D)
        {
            colorShadows[direction3D][direction2D] = false;
            return;
            switch (direction2D)
            {
                case 0:
                    colorShadow[direction3D][2] = 0;
                    colorShadow[direction3D][3] = 0;
                    break;
                case 1:
                    colorShadow[direction3D][0] = 0;
                    colorShadow[direction3D][1] = 0;
                    break;
                case 2:
                    colorShadow[direction3D][2] = 0;
                    colorShadow[direction3D][1] = 0;
                    break;
                case 3:
                    colorShadow[direction3D][3] = 0;
                    colorShadow[direction3D][0] = 0;
                    break;
            }
        }
        /// <summary>
        /// 0上，1下，2左，3右
        /// </summary>
        public void SetColorShadowAdd(int direction3D, int direction2D, Voxel3D edgeConjugate, List<UpdateShadowUnitData> tempAllUpdateShadow) 
        {
            switch (direction3D)
            {
                case 0:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowAdd(0, 0);
                            edgeConjugate.SetColorShadowAdd(3, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowAdd(0, 1);
                            edgeConjugate.SetColorShadowAdd(2, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowAdd(0, 2);
                            edgeConjugate.SetColorShadowAdd(4, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowAdd(0, 3);
                            edgeConjugate.SetColorShadowAdd(5, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 7:
                            //this.SetColorShadowAdd(0, 6);
                            edgeConjugate.SetColorShadowAdd(2, 5);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                    }
                    break;
                case 1:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowAdd(1, 0);
                            edgeConjugate.SetColorShadowAdd(3, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowAdd(1, 1);
                            edgeConjugate.SetColorShadowAdd(2, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowAdd(1, 2);
                            edgeConjugate.SetColorShadowAdd(5, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowAdd(1, 3);
                            edgeConjugate.SetColorShadowAdd(4, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            break;
                    }
                    break;
                case 2:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowAdd(2, 0);
                            edgeConjugate.SetColorShadowAdd(5, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 1:
                            edgeConjugate.SetColorShadowAdd(4, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            this.SetColorShadowAdd(2, 1);
                            break;
                        case 2:
                            edgeConjugate.SetColorShadowAdd(0, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            this.SetColorShadowAdd(2, 2);
                            break;
                        case 3:
                            edgeConjugate.SetColorShadowAdd(1, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            this.SetColorShadowAdd(2, 3);
                            break;
                    }
                    break;
                case 3:
                    switch (direction2D)
                    {
                        case 0:
                            edgeConjugate.SetColorShadowAdd(4, 0);                           
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            this.SetColorShadowAdd(3, 0);
                            break;
                        case 1:
                            edgeConjugate.SetColorShadowAdd(5, 0);                          
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            this.SetColorShadowAdd(3, 1);
                            break;
                        case 2:
                            edgeConjugate.SetColorShadowAdd(0, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            this.SetColorShadowAdd(3, 2);
                            break;
                        case 3:
                            edgeConjugate.SetColorShadowAdd(1, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            this.SetColorShadowAdd(3, 3);
                            break;
                    }
                    break;
                case 4:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowAdd(4, 0);
                            edgeConjugate.SetColorShadowAdd(3, 0);
                            tempAllUpdateShadow.Add( new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowAdd(4, 1);
                            edgeConjugate.SetColorShadowAdd(2, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowAdd(4, 2);
                            edgeConjugate.SetColorShadowAdd(1, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowAdd(4, 3);
                            edgeConjugate.SetColorShadowAdd(0, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate)); ;
                            break;
                    }
                    break;
                case 5:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowAdd(5, 0);
                            edgeConjugate.SetColorShadowAdd(3, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowAdd(5, 1);
                            edgeConjugate.SetColorShadowAdd(2, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowAdd(5, 2);
                            edgeConjugate.SetColorShadowAdd(0, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowAdd(5, 3);
                            edgeConjugate.SetColorShadowAdd(1, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            break;
                    }
                    break;
            }
        }

        public void SetColorShadowCornerAdd(int direction3D, int direction2D, Voxel3D edgeConjugate, List<UpdateShadowUnitData> tempAllUpdateShadow)
        {
            switch (direction3D)
            {
                case 0:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(0, 4);
                                edgeConjugate.SetColorShadowAdd(3, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(0, 4);
                                edgeConjugate.SetColorShadowAdd(5, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(0, 5);
                                edgeConjugate.SetColorShadowAdd(2, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(0, 5);
                                edgeConjugate.SetColorShadowAdd(4, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(0, 6);
                                edgeConjugate.SetColorShadowAdd(3, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(0, 6);
                                edgeConjugate.SetColorShadowAdd(4, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(0, 7);
                                edgeConjugate.SetColorShadowAdd(2, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(0, 7);
                                edgeConjugate.SetColorShadowAdd(5, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 1:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(1, 4);
                                edgeConjugate.SetColorShadowAdd(3, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(1, 4);
                                edgeConjugate.SetColorShadowAdd(4, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(1, 5);
                                edgeConjugate.SetColorShadowAdd(2, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(1, 5);
                                edgeConjugate.SetColorShadowAdd(5, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(1, 6);
                                edgeConjugate.SetColorShadowAdd(3, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(1, 6);
                                edgeConjugate.SetColorShadowAdd(5, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(1, 7);
                                edgeConjugate.SetColorShadowAdd(2, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(1, 7);
                                edgeConjugate.SetColorShadowAdd(4, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 2:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(2, 4);
                                edgeConjugate.SetColorShadowAdd(1, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(2, 4);
                                edgeConjugate.SetColorShadowAdd(5, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(2, 5);
                                edgeConjugate.SetColorShadowAdd(0, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(2, 5);
                                edgeConjugate.SetColorShadowAdd(4, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(2, 6);
                                edgeConjugate.SetColorShadowAdd(0, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(2, 6);
                                edgeConjugate.SetColorShadowAdd(5, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(2, 7);
                                edgeConjugate.SetColorShadowAdd(1, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(2, 7);
                                edgeConjugate.SetColorShadowAdd(4, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 3:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(3, 4);
                                edgeConjugate.SetColorShadowAdd(1, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(3, 4);
                                edgeConjugate.SetColorShadowAdd(4, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(3, 5);
                                edgeConjugate.SetColorShadowAdd(0, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(3, 5);
                                edgeConjugate.SetColorShadowAdd(5, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(3, 6);
                                edgeConjugate.SetColorShadowAdd(0, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowAdd(3, 6);
                                edgeConjugate.SetColorShadowAdd(4, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(3, 7);
                                edgeConjugate.SetColorShadowAdd(1, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowAdd(3, 7);
                                edgeConjugate.SetColorShadowAdd(5, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 4:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(4, 4);
                                edgeConjugate.SetColorShadowAdd(3, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(4, 4);
                                edgeConjugate.SetColorShadowAdd(0, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(4, 5);
                                edgeConjugate.SetColorShadowAdd(2, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(4, 5);
                                edgeConjugate.SetColorShadowAdd(1, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(4, 6);
                                edgeConjugate.SetColorShadowAdd(3, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(4, 6);
                                edgeConjugate.SetColorShadowAdd(1, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(4, 7);
                                edgeConjugate.SetColorShadowAdd(2, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(4, 7);
                                edgeConjugate.SetColorShadowAdd(0, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 5:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(5, 4);
                                edgeConjugate.SetColorShadowAdd(3, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(5, 4);
                                edgeConjugate.SetColorShadowAdd(1, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(5, 5);
                                edgeConjugate.SetColorShadowAdd(2, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(5, 5);
                                edgeConjugate.SetColorShadowAdd(0, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowAdd(5, 6);
                                edgeConjugate.SetColorShadowAdd(3, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowAdd(5, 6);
                                edgeConjugate.SetColorShadowAdd(0, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowAdd(5, 7);
                                edgeConjugate.SetColorShadowAdd(2, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowAdd(5, 7);
                                edgeConjugate.SetColorShadowAdd(1, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                    }
                    break;
            }
        }

        public void SetColorShadowRemove(int direction3D, int direction2D, Voxel3D edgeConjugate, List<UpdateShadowUnitData> tempAllUpdateShadow)
        {
            switch (direction3D)
            {
                case 0:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowRemove(0, 0);
                            edgeConjugate.SetColorShadowRemove(3, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowRemove(0, 1);
                            edgeConjugate.SetColorShadowRemove(2, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowRemove(0, 2);
                            edgeConjugate.SetColorShadowRemove(4, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowRemove(0, 3);
                            edgeConjugate.SetColorShadowRemove(5, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 7:
                            //this.SetColorShadowRemove(0, 6);
                            edgeConjugate.SetColorShadowRemove(2, 5);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                    }
                    break;
                case 1:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowRemove(1, 0);
                            edgeConjugate.SetColorShadowRemove(3, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowRemove(1, 1);
                            edgeConjugate.SetColorShadowRemove(2, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowRemove(1, 2);
                            edgeConjugate.SetColorShadowRemove(5, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowRemove(1, 3);
                            edgeConjugate.SetColorShadowRemove(4, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            break;
                    }
                    break;
                case 2:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowRemove(2, 0);
                            edgeConjugate.SetColorShadowRemove(5, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            break;
                        case 1:
                            edgeConjugate.SetColorShadowRemove(4, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            this.SetColorShadowRemove(2, 1);
                            break;
                        case 2:
                            edgeConjugate.SetColorShadowRemove(0, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            this.SetColorShadowRemove(2, 2);
                            break;
                        case 3:
                            edgeConjugate.SetColorShadowRemove(1, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            this.SetColorShadowRemove(2, 3);
                            break;
                    }
                    break;
                case 3:
                    switch (direction2D)
                    {
                        case 0:
                            edgeConjugate.SetColorShadowRemove(4, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            this.SetColorShadowRemove(3, 0);
                            break;
                        case 1:
                            edgeConjugate.SetColorShadowRemove(5, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            this.SetColorShadowRemove(3, 1);
                            break;
                        case 2:
                            edgeConjugate.SetColorShadowRemove(0, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            this.SetColorShadowRemove(3, 2);
                            break;
                        case 3:
                            edgeConjugate.SetColorShadowRemove(1, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            this.SetColorShadowRemove(3, 3);
                            break;
                    }
                    break;
                case 4:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowRemove(4, 0);
                            edgeConjugate.SetColorShadowRemove(3, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowRemove(4, 1);
                            edgeConjugate.SetColorShadowRemove(2, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowRemove(4, 2);
                            edgeConjugate.SetColorShadowRemove(1, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowRemove(4, 3);
                            edgeConjugate.SetColorShadowRemove(0, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate)); ;
                            break;
                    }
                    break;
                case 5:
                    switch (direction2D)
                    {
                        case 0:
                            this.SetColorShadowRemove(5, 0);
                            edgeConjugate.SetColorShadowRemove(3, 1);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            break;
                        case 1:
                            this.SetColorShadowRemove(5, 1);
                            edgeConjugate.SetColorShadowRemove(2, 0);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            break;
                        case 2:
                            this.SetColorShadowRemove(5, 2);
                            edgeConjugate.SetColorShadowRemove(0, 3);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            break;
                        case 3:
                            this.SetColorShadowRemove(5, 3);
                            edgeConjugate.SetColorShadowRemove(1, 2);
                            tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            break;
                    }
                    break;
            }
        }


        public void SetColorShadowCornerRemove(int direction3D, int direction2D, Voxel3D edgeConjugate, List<UpdateShadowUnitData> tempAllUpdateShadow)
        {

            switch (direction3D)
            {
                case 0:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(0, 4);
                                edgeConjugate.SetColorShadowRemove(3, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(0, 4);
                                edgeConjugate.SetColorShadowRemove(5, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(0, 5);
                                edgeConjugate.SetColorShadowRemove(2, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(0, 5);
                                edgeConjugate.SetColorShadowRemove(4, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(0, 6);
                                edgeConjugate.SetColorShadowRemove(3, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(0, 6);
                                edgeConjugate.SetColorShadowRemove(4, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(0, 7);
                                edgeConjugate.SetColorShadowRemove(2, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(0, 7);
                                edgeConjugate.SetColorShadowRemove(5, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 1:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(1, 4);
                                edgeConjugate.SetColorShadowRemove(3, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(1, 4);
                                edgeConjugate.SetColorShadowRemove(4, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(1, 5);
                                edgeConjugate.SetColorShadowRemove(2, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(1, 5);
                                edgeConjugate.SetColorShadowRemove(5, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(1, 6);
                                edgeConjugate.SetColorShadowRemove(3, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(1, 6);
                                edgeConjugate.SetColorShadowRemove(5, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(1, 7);
                                edgeConjugate.SetColorShadowRemove(2, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(1, 7);
                                edgeConjugate.SetColorShadowRemove(4, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 2:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(2, 4);
                                edgeConjugate.SetColorShadowRemove(1, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(2, 4);
                                edgeConjugate.SetColorShadowRemove(5, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(2, 5);
                                edgeConjugate.SetColorShadowRemove(0, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(2, 5);
                                edgeConjugate.SetColorShadowRemove(4, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(2, 6);
                                edgeConjugate.SetColorShadowRemove(0, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(2, 6);
                                edgeConjugate.SetColorShadowRemove(5, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(2, 7);
                                edgeConjugate.SetColorShadowRemove(1, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(2, 7);
                                edgeConjugate.SetColorShadowRemove(4, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 3:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(3, 4);
                                edgeConjugate.SetColorShadowRemove(1, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(3, 4);
                                edgeConjugate.SetColorShadowRemove(4, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(3, 5);
                                edgeConjugate.SetColorShadowRemove(0, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(3, 5);
                                edgeConjugate.SetColorShadowRemove(5, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(3, 6);
                                edgeConjugate.SetColorShadowRemove(0, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[4])
                            {
                                this.SetColorShadowRemove(3, 6);
                                edgeConjugate.SetColorShadowRemove(4, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(4, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(3, 7);
                                edgeConjugate.SetColorShadowRemove(1, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[5])
                            {
                                this.SetColorShadowRemove(3, 7);
                                edgeConjugate.SetColorShadowRemove(5, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(5, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 4:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(4, 4);
                                edgeConjugate.SetColorShadowRemove(3, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(4, 4);
                                edgeConjugate.SetColorShadowRemove(0, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(4, 5);
                                edgeConjugate.SetColorShadowRemove(2, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(4, 5);
                                edgeConjugate.SetColorShadowRemove(1, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(4, 6);
                                edgeConjugate.SetColorShadowRemove(3, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(4, 6);
                                edgeConjugate.SetColorShadowRemove(1, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(4, 7);
                                edgeConjugate.SetColorShadowRemove(2, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(4, 7);
                                edgeConjugate.SetColorShadowRemove(0, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                    }
                    break;
                case 5:
                    switch (direction2D)
                    {
                        case 0:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(5, 4);
                                edgeConjugate.SetColorShadowRemove(3, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(5, 4);
                                edgeConjugate.SetColorShadowRemove(1, 5);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                        case 1:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(5, 5);
                                edgeConjugate.SetColorShadowRemove(2, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(5, 5);
                                edgeConjugate.SetColorShadowRemove(0, 4);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 2:
                            if (edgeConjugate.surfaces[3])
                            {
                                this.SetColorShadowRemove(5, 6);
                                edgeConjugate.SetColorShadowRemove(3, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(3, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[0])
                            {
                                this.SetColorShadowRemove(5, 6);
                                edgeConjugate.SetColorShadowRemove(0, 7);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(0, edgeConjugate));
                            }
                            break;
                        case 3:
                            if (edgeConjugate.surfaces[2])
                            {
                                this.SetColorShadowRemove(5, 7);
                                edgeConjugate.SetColorShadowRemove(2, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(2, edgeConjugate));
                            }
                            if (edgeConjugate.surfaces[1])
                            {
                                this.SetColorShadowRemove(5, 7);
                                edgeConjugate.SetColorShadowRemove(1, 6);
                                tempAllUpdateShadow.Add(new UpdateShadowUnitData(1, edgeConjugate));
                            }
                            break;
                    }
                    break;
            }
        }

        public int GetChunkIndexNoBorder(int direction)
        {
            switch (direction)
            {
                case 0:
                    return chunkIndex + 1;
                case 1:
                    return chunkIndex - 1;
                case 2:
                    return chunkIndex + 16;
                case 3:
                    return chunkIndex - 16;
                case 4:
                    return chunkIndex + 256;
                case 5:
                    return chunkIndex - 256;
            }

            return chunkIndex;
        }

        public  int Get_ChunkIndexNoBorder_AddX()
        {
            return chunkIndex + 1;
        }

        public int Get_ChunkIndexNoBorder_RemoveX()
        {
            return chunkIndex - 1;
        }

        public int Get_ChunkIndexNoBorder_AddY()
        {
            return chunkIndex + 16;
        }

        public int Get_ChunkIndexNoBorder_RemoveY()
        {
            return chunkIndex - 16;
        }

        public int Get_ChunkIndexNoBorder_AddZ()
        {
            return chunkIndex + 256;
        }

        public int Get_ChunkIndexNoBorder_RemoveZ()
        {
            return chunkIndex - 256;
        }

    }
}
